package edu.zut.hys.chatpageapplication.slice;

import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_PARENT;

import edu.zut.hys.chatpageapplication.MainAbility;
import edu.zut.hys.chatpageapplication.ResourceTable;
import edu.zut.hys.chatpageapplication.bean.AMessage;
import edu.zut.hys.chatpageapplication.bean.ImageLineItem;
import edu.zut.hys.chatpageapplication.location.LocationBean;
import edu.zut.hys.chatpageapplication.provider.ImageLineProvider;
import edu.zut.hys.chatpageapplication.provider.MessageItemProvider;
import edu.zut.hys.chatpageapplication.utils.LogUtil;
import edu.zut.hys.chatpageapplication.utils.PictureManager;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.*;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;

import ohos.agp.window.dialog.CommonDialog;
import ohos.agp.window.dialog.IDialog;
import ohos.agp.window.dialog.PopupDialog;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Context;
import ohos.bundle.IBundleManager;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.location.*;
import ohos.utils.net.Uri;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class MainAbilitySlice extends AbilitySlice {

    private ListContainer listContainer;

    private MessageItemProvider messageItemProvider;

    private ArrayList<AMessage> messageData;

    private Button sendButton;

    private Button moreButton;

    private Button cameraButton;

    private Button imageButton;

    private Button positionButton;

    private TextField messageTextField;

    private Text nameText;

    private Intent intent = new Intent();

    private DirectionalLayout top;
    private DirectionalLayout chats;
    private DirectionalLayout input;
    private DirectionalLayout root;
    private DependentLayout addpop;

    //定位-------------------------------------------------------------------------------------
    private static final String TAG = MainAbility.class.getSimpleName();

    private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, TAG);

    private static final int EVENT_ID = 0x12;

    private static final String PERM_LOCATION = "ohos.permission.LOCATION";

    private final LocatorResult locatorResult = new LocatorResult();

    private Context context;

    private Locator locator;

    private GeoConvert geoConvert;

    private List<GeoAddress> gaList;

    private LocationBean locationDetails;

    private StringBuffer position;
    //定位结束-------------------------------------------------------------------------------------


    //图片开始-------------------------------------------------------------------------------------
    private List<Uri> imagePathElements = null;

    private PictureManager pictureManager;

    private ImageLineProvider imageLineProvider;

    private ListContainer imagelistContainer;

    private List<ImageLineItem> imageLineItemList;

    private Button closeimagebutton;

    CommonDialog dialog;

    //图片结束-------------------------------------------------------------------------------------

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        initComponents();
        initMessageData();
        initProvider();
        initImageData();
        register(this);
    }

    @Override
    public void onActive() {
        super.onActive();
    }


    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    @Override
    protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
        switch (requestCode) {
            case 1:
                if(resultData.hasParameter("uri")){
                    //showTips(this,"come from takePhoto +" + resultData.getStringParam("uri"));
                    addAndUpdateMessage(messageData.size(), String.valueOf(resultData.getStringParam("uri")),"image");
                }
            default:
                return;
        }
    }

    private void initComponents() {
        listContainer = (ListContainer) findComponentById(ResourceTable.Id_list_container);
        listContainer.setClickedListener(component -> {
            messageTextField.clearFocus();
            if( addpop.getVisibility() == Component.VISIBLE )
                addpop.setVisibility( Component.HIDE );
        });
        listContainer.setItemClickedListener((listContainer, component, i, l) -> {
            messageTextField.clearFocus();
            if (addpop.getVisibility() == Component.VISIBLE)
                addpop.setVisibility(Component.HIDE);
        });
        listContainer.setScrollListener(() -> {
            messageTextField.clearFocus();
            if (addpop.getVisibility() == Component.VISIBLE)
                addpop.setVisibility(Component.HIDE);
        });
        sendButton = (Button) findComponentById(ResourceTable.Id_session_button_send);
        moreButton = (Button) findComponentById(ResourceTable.Id_session_button_more);
        messageTextField = (TextField) findComponentById(ResourceTable.Id_text_message);
        nameText = (Text) findComponentById(ResourceTable.Id_text_name);
        top = (DirectionalLayout)findComponentById(ResourceTable.Id_top);
        chats = (DirectionalLayout)findComponentById(ResourceTable.Id_chats);
        input = (DirectionalLayout)findComponentById(ResourceTable.Id_input);
        root = (DirectionalLayout)findComponentById(ResourceTable.Id_root);
        addpop = (DependentLayout)findComponentById(ResourceTable.Id_addpop);
        Component moreinput =
                LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_more_input_dialog, null, false);
        cameraButton = (Button) moreinput.findComponentById(ResourceTable.Id_session_button_camera);
        imageButton = (Button) moreinput.findComponentById(ResourceTable.Id_session_button_image);
        positionButton = (Button) moreinput.findComponentById(ResourceTable.Id_session_button_position);

        cameraButton.setClickedListener(listener -> {
            Operation operation = new Intent.OperationBuilder()
                    .withDeviceId("")
                    .withBundleName("edu.zut.hys.fractionskate")
                    .withAbilityName("edu.zut.hys.chatpageapplication.TakePhotoAbility")
                    .build();
            Intent intent = new Intent();
            intent.setOperation(operation);
            startAbilityForResult(intent,1);
        });

        positionButton.setClickedListener(component1 -> {
            registerLocationEvent();
        });

        imageButton.setClickedListener(component1 -> {
            dialog = new CommonDialog(getContext());

            initImageData();
            DirectionalLayout directionalLayout = new DirectionalLayout(getContext());
            Component component2;
            component2 = LayoutScatter.getInstance(this).parse(ResourceTable.Layout_image_main, null, false);
            imagelistContainer= (ListContainer) component2.findComponentById(ResourceTable.Id_list_container);
            closeimagebutton = (Button) component2.findComponentById(ResourceTable.Id_close_image_button);
            closeimagebutton.setClickedListener(component3 -> {
                dialog.destroy();
            });
            directionalLayout.addComponent(component2);
            initImageListContainer();

            dialog.setContentCustomComponent(directionalLayout);
            dialog.setTitleText("图片");
            dialog.setSize(MATCH_PARENT,MATCH_PARENT);
            //dialog.setContentText("This is CommonDialog Content area.");
            dialog.setButton(IDialog.BUTTON3, "CONFIRM", (iDialog, i) -> iDialog.destroy());
            dialog.show();
            //addAndUpdateMessage(messageData.size(),"message","image");
        });
        addpop.addComponent(moreinput);
        
        messageTextField.setFocusChangedListener((component, isFocused) -> {
            if (isFocused) {
                addpop.setVisibility( Component.VISIBLE );
            }
        });
        sendButton.setClickedListener(component -> {
            String message = messageTextField.getText();
            if(!message.equals("")){
                addAndUpdateMessage(messageData.size(),message,"string");
                messageTextField.setText("");
            }
            messageTextField.clearFocus();
        });
        moreButton.setClickedListener(component -> {
//            PopupDialog popupDialog = new PopupDialog(getContext(), component, MATCH_PARENT,800);
//            RadioContainer radioContainer = new RadioContainer(getContext());
//            radioContainer.setPadding(10, 10, 10, 10);
//            Component moreinput =
//                    LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_more_input_dialog, null, false);
//            cameraButton = (Button) moreinput.findComponentById(ResourceTable.Id_session_button_camera);
//            imageButton = (Button) moreinput.findComponentById(ResourceTable.Id_session_button_image);
//            positionButton = (Button) moreinput.findComponentById(ResourceTable.Id_session_button_position);
//
//            cameraButton.setClickedListener(listener -> {
//                popupDialog.destroy();
//                Operation operation = new Intent.OperationBuilder()
//                        .withDeviceId("")
//                        .withBundleName("edu.zut.hys.fractionskate")
//                        .withAbilityName("edu.zut.hys.chatpageapplication.TakePhotoAbility")
//                        .build();
//                Intent intent = new Intent();
//                intent.setOperation(operation);
//                startAbilityForResult(intent,1);
//            });
//
//            positionButton.setClickedListener(component1 -> {
//                registerLocationEvent();
//            });
//
//            imageButton.setClickedListener(component1 -> {
//                dialog = new CommonDialog(getContext());
//
//                initImageData();
//                DirectionalLayout directionalLayout = new DirectionalLayout(getContext());
//                Component component2;
//                component2 = LayoutScatter.getInstance(this).parse(ResourceTable.Layout_image_main, null, false);
//                imagelistContainer= (ListContainer) component2.findComponentById(ResourceTable.Id_list_container);
//                closeimagebutton = (Button) component2.findComponentById(ResourceTable.Id_close_image_button);
//                closeimagebutton.setClickedListener(component3 -> {
//                    dialog.destroy();
//                });
//                directionalLayout.addComponent(component2);
//                initImageListContainer();
//
//                dialog.setContentCustomComponent(directionalLayout);
//                dialog.setTitleText("图片");
//                dialog.setSize(MATCH_PARENT,MATCH_PARENT);
//                //dialog.setContentText("This is CommonDialog Content area.");
//                dialog.setButton(IDialog.BUTTON3, "CONFIRM", (iDialog, i) -> iDialog.destroy());
//                dialog.show();
//                //addAndUpdateMessage(messageData.size(),"message","image");
//            });
//
//            radioContainer.addComponent(moreinput);
//            popupDialog.setCustomComponent(radioContainer);
//            popupDialog.setMode(LayoutAlignment.BOTTOM);
//            popupDialog.setBackColor(new Color(Color.getIntColor("#E8EAEE")));
//            popupDialog.setAutoClosable(true);
//            popupDialog.show();
            messageTextField.clearFocus();
            if( addpop.getVisibility() == Component.HIDE )
                addpop.setVisibility( Component.VISIBLE );
        });
    }

    private void showTips(Context context, String msg) {
        getUITaskDispatcher().asyncDispatch(() -> new ToastDialog(context).setText(msg).show());
    }

//    private void startAbility(String abilityName) {
//        Operation operation = new Intent.OperationBuilder()
//                .withDeviceId("")
//                .withBundleName("edu.zut.hys.fractionskate")
//                .withAbilityName("edu.zut.hys.chatpageapplication"+abilityName)
//                .build();
//        Intent intent = new Intent();
//        intent.setOperation(operation);
//        startAbility(intent);
//    }

    private void initProvider() {
        messageItemProvider = new MessageItemProvider(this, messageData);
        listContainer.setItemProvider(messageItemProvider);
        listContainer.setReboundEffect(true);
    }

    private void initMessageData() {
        messageData = new ArrayList<>();
        addMessage(messageData.size(), "你好","string");
    }

    public void addAndUpdateMessage(int index,String message,String type) {
        addMessage(index,message,type);
        messageItemProvider.update(messageData);
    }

    private void addMessage(int index, String message,String type) {
        messageData.add(new AMessage("User " + index, message,type));
    }

    public int getMessageDataSize(){
        return messageData.size();
    }


    //图片服务-------------------------------------------------------------------------------------

    private void initImageData(){
        pictureManager = new PictureManager(getApplicationContext());
        imagePathElements = pictureManager.getimageElements();
        LogUtil.info(TAG,"The size is " + imagePathElements.size());
    }

    private void initImageListContainer() {
        imagelistContainer.setReboundEffect(true);
        //imagePathElements = pictureManager.getimageElements();

        LogUtil.info(TAG,"imagePathElements.size() : "+imagePathElements.size());

        imageLineItemList = new ArrayList<>();
        for(int i = 0; i < 6; i++){
            ImageLineItem imageLineItem = new ImageLineItem(i);
            Uri[] uris = new Uri[3];
            uris[0] = imagePathElements.get(i*3);
            uris[1] = imagePathElements.get(i*3+1);
            uris[2] = imagePathElements.get(i*3+2);
            imageLineItem.setUris(uris);
            imageLineItemList.add(imageLineItem);
        }
        LogUtil.info(TAG,"imageLineItemList.size() : "+imageLineItemList.size());
        imageLineProvider = new ImageLineProvider(imageLineItemList,this);
        imageLineProvider.setMainAbilitySlice(this);
        imagelistContainer.setItemProvider(imageLineProvider);
    }

    public  CommonDialog getDialog(){
        return this.dialog;
    }

    //图片结束-------------------------------------------------------------------------------------



    //定位服务-------------------------------------------------------------------------------------
    private void notifyLocationChange(LocationBean locationDetails) {
        update(locationDetails);
    }

    private void update(LocationBean locationDetails) {
//        locationInfoText.setText("");
//        locationInfoText.append("Latitude : " + locationDetails.getLatitude() + System.lineSeparator());
//        locationInfoText.append("Longitude : " + locationDetails.getLongitude() + System.lineSeparator());
//        locationInfoText.append("Speed : " + locationDetails.getSpeed() + " m/s" + System.lineSeparator());
//        locationInfoText.append("Direction : " + locationDetails.getDirection() + System.lineSeparator());
//        locationInfoText.append("TimeStamp : " + locationDetails.getTime());
//
        position = new StringBuffer("");
        position.append(
                "SubAdministrative : " + locationDetails.getSubAdministrative());
        position.append("RoadName : " + locationDetails.getRoadName());
        position.append("Locality : " + locationDetails.getLocality());
        position.append("Administrative : " + locationDetails.getAdministrative());
        position.append("CountryName : " + locationDetails.getCountryName());

        addAndUpdateMessage(messageData.size(), String.valueOf(position),"string");

        unregisterLocationEvent();
    }

    private final EventHandler handler = new EventHandler(EventRunner.current()) {
        @Override
        protected void processEvent(InnerEvent event) {
            if (event.eventId == EVENT_ID) {
                notifyLocationChange(locationDetails);
            }
        }
    };

    private void register(Context ability) {
        context = ability;
        requestPermission();
    }

    private void registerLocationEvent() {
        if (hasPermissionGranted()) {
            int timeInterval = 0;
            int distanceInterval = 0;
            locator = new Locator(context);
            RequestParam requestParam = new RequestParam(RequestParam.PRIORITY_ACCURACY, timeInterval, distanceInterval);
            locator.startLocating(requestParam, locatorResult);
        }
    }

    private void unregisterLocationEvent() {
        if (locator != null) {
            locator.stopLocating(locatorResult);
        }
    }

    private boolean hasPermissionGranted() {
        return context.verifySelfPermission(PERM_LOCATION) == IBundleManager.PERMISSION_GRANTED;
    }

    private void requestPermission() {
        if (context.verifySelfPermission(PERM_LOCATION) != IBundleManager.PERMISSION_GRANTED) {
            context.requestPermissionsFromUser(new String[] {PERM_LOCATION}, 0);
        }
    }

    private class LocatorResult implements LocatorCallback {
        @Override
        public void onLocationReport(Location location) {
            HiLog.info(LABEL_LOG, "%{public}s",
                    "onLocationReport : " + location.getLatitude() + "-" + location.getAltitude());
            setLocation(location);
        }

        @Override
        public void onStatusChanged(int statusCode) {
            HiLog.info(LABEL_LOG, "%{public}s", "MyLocatorCallback onStatusChanged : " + statusCode);
        }

        @Override
        public void onErrorReport(int errorCode) {
            HiLog.info(LABEL_LOG, "%{public}s", "MyLocatorCallback onErrorReport : " + errorCode);
        }
    }

    private void setLocation(Location location) {
        if (location != null) {
            Date date = new Date(location.getTimeStamp());
            locationDetails = new LocationBean();
            locationDetails.setTime(date.toString());
            locationDetails.setLatitude(location.getLatitude());
            locationDetails.setLongitude(location.getLongitude());
            locationDetails.setPrecision(location.getAccuracy());
            locationDetails.setSpeed(location.getSpeed());
            locationDetails.setDirection(location.getDirection());
            fillGeoInfo(locationDetails, location.getLatitude(), location.getLongitude());
            handler.sendEvent(EVENT_ID);
            gaList.clear();
        } else {
            HiLog.info(LABEL_LOG, "%{public}s", "EventNotifier or Location response is null");
            new ToastDialog(context).setText("EventNotifier or Location response is null").show();
        }
    }

    private void fillGeoInfo(LocationBean locationDetails, double geoLatitude, double geoLongitude) {
        if (geoConvert == null) {
            geoConvert = new GeoConvert();
        }
        if (geoConvert.isGeoAvailable()) {
            try {
                gaList = geoConvert.getAddressFromLocation(geoLatitude, geoLongitude, 1);
                if (!gaList.isEmpty()) {
                    GeoAddress geoAddress = gaList.get(0);
                    setGeo(locationDetails, geoAddress);
                }
            } catch (IllegalArgumentException | IOException e) {
                HiLog.error(LABEL_LOG, "%{public}s", "fillGeoInfo exception");
            }
        }
    }

    private void setGeo(LocationBean locationDetails, GeoAddress geoAddress) {
        locationDetails.setRoadName(checkIfNullOrEmpty(geoAddress.getRoadName()));
        locationDetails.setLocality(checkIfNullOrEmpty(geoAddress.getLocality()));
        locationDetails.setSubAdministrative(checkIfNullOrEmpty(geoAddress.getSubAdministrativeArea()));
        locationDetails.setAdministrative(checkIfNullOrEmpty(geoAddress.getAdministrativeArea()));
        locationDetails.setCountryName(checkIfNullOrEmpty(geoAddress.getCountryName()));
    }

    private String checkIfNullOrEmpty(String value) {
        if (value == null || value.isEmpty()) {
            return "NA";
        }
        return value;
    }

    //定位服务结束-------------------------------------------------------------------------------------
}
